package cc.eddic.pratice.programmingparadigms.nginxlog.impl;

import cc.eddic.pratice.programmingparadigms.nginxlog.LogItem;
import cc.eddic.pratice.programmingparadigms.nginxlog.LogItemParser;
import cc.eddic.pratice.programmingparadigms.nginxlog.NginxLogItem;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;


public class LogItemParserZyzImpl implements LogItemParser {


    @Override
    public Optional<LogItem> parse(NginxLogItem nginxLogItem) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z", Locale.ENGLISH);
        LocalDateTime localDateTime = LocalDateTime.parse(nginxLogItem.getTime(), formatter);

        String request = nginxLogItem.getRequest();
        String[] arrStrRequestElements = request.split(" ");
        if (arrStrRequestElements.length != 3) {
            return Optional.empty();
        }

        String strMethod = arrStrRequestElements[0];
        if ( ! (strMethod.equals("GET")  || strMethod.equals("PUT")  || strMethod.equals("POST") ) ){
            return Optional.empty();
        }

        String strPath = null, strQuery = null;
        if (arrStrRequestElements[1].equals("/")) {
            strPath = "/";
        }
        else if (arrStrRequestElements[1].contains("?")) {
            int i = arrStrRequestElements[1].indexOf("?");
            strPath = arrStrRequestElements[1].substring(0, i);
            strQuery = arrStrRequestElements[1].substring(i + 1);
        }
        else {
            strPath = arrStrRequestElements[1];
        }

        Map<String, String> mapQueries = new HashMap<>();
        if (strQuery != null) {
            if (strQuery.contains("&")) {
                String[] arrStrQueries = strQuery.split("&");
                for (String query : arrStrQueries) {
                    String key = query.split("=")[0];
                    String value = query.split("=")[1];
                    mapQueries.put(key, value);
                }
            }
            else {
                int indexEqualSign = strQuery.indexOf("=");
                if (indexEqualSign != -1) { mapQueries.put(strQuery.substring(0, indexEqualSign),
                        strQuery.substring(indexEqualSign + 1) ); }
            }

        }

            String strProtocol = arrStrRequestElements[2];

            return Optional.of(new LogItem(nginxLogItem.getIp(),
                            localDateTime,
                            strMethod,
                            strPath,
                            mapQueries,
                            strProtocol,
                            Integer.parseInt(nginxLogItem.getStatus()) ,
                            Long.parseLong(nginxLogItem.getBytes()) ,
                            nginxLogItem.getReferer(),
                            nginxLogItem.getUserAgent()
                    )
            );

    }


}
